﻿using Serilog;
using Serilog.Debugging;
using Serilog.Events;
using Serilog.Formatting.Json;
using Serilog.Sinks.Elasticsearch;
using Serilog.Sinks.File;
using Serilog.Sinks.SystemConsole.Themes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Sustainalytics.ScreeningTool.BL.Serilog
{
    class CompanyScreeningSerilog
    {
        public static Lazy<CompanyScreeningSerilog> _lazyLog = new Lazy<CompanyScreeningSerilog>(InitLog, LazyThreadSafetyMode.ExecutionAndPublication);
        private readonly ILogger _logger;

        public static CompanyScreeningSerilog Log
        {
            get
            {
                return _lazyLog.Value;
            }
        }

        public static CompanyScreeningSerilog InitLog()
        {
            var log = new CompanyScreeningSerilog();

            log.Ping();

            return log;

        }

        public CompanyScreeningSerilog()
        {
            var loggerConfig = new LoggerConfiguration()
                  .MinimumLevel.Debug()
                  .WriteTo.Console(theme: SystemConsoleTheme.Literate)
                  .WriteTo.Elasticsearch(new ElasticsearchSinkOptions(new Uri("http://localhost:9200"))
                  {
                      IndexFormat = "testaccounts-{0:yyyy.MM.dd}",
                      AutoRegisterTemplate = true,
                      RegisterTemplateFailure = RegisterTemplateRecovery.IndexAnyway,
                      FailureCallback = e => Console.WriteLine("Unable to submit event " + e.MessageTemplate),
                      EmitEventFailure = EmitEventFailureHandling.WriteToSelfLog |
                                         EmitEventFailureHandling.WriteToFailureSink |
                                         EmitEventFailureHandling.RaiseCallback,
                      FailureSink = new FileSink("../failuresScreeningToolService-" + DateTime.Now.Ticks.ToString() + ".txt", new JsonFormatter(), null)
                  });
            _logger = loggerConfig.CreateLogger();

            SelfLog.Enable(Console.Error);
        }

        public void Ping()
        {
            var eventId = 1;

            if (_logger.IsEnabled(LogEventLevel.Debug))
                _logger.Debug("Ping {0}", eventId);
        }

        public void LoadTemplateCriteriaTypeFiveService(Guid criteriaTemplateId)
        {
            var eventId = 2;

            if (_logger.IsEnabled(LogEventLevel.Information))
                _logger.Information($"{eventId}, LoadTemplateCriteriaTypeFiveService {criteriaTemplateId.ToString()}");
        }

        public void LoadTemplateCriteriaType25Service(Guid criteriaTemplateId)
        {
            var eventId = 3;

            if (_logger.IsEnabled(LogEventLevel.Information))
                _logger.Information($"{eventId}, LoadTemplateCriteriaType25Service {criteriaTemplateId.ToString()}");
        }

        public void ClearResultOutput(Guid filterId)
        {
            var eventId = 4;

            if (_logger.IsEnabled(LogEventLevel.Information))
                _logger.Information($"{eventId}, ClearResultOutput {filterId.ToString()}");
        }

        public void ClearResultOutputSuccess(Guid filterId)
        {
            var eventId = 5;

            if (_logger.IsEnabled(LogEventLevel.Information))
                _logger.Information($"{eventId}, ClearResultOutputSuccess {filterId.ToString()}");
        }

        public void ClearResultOutputError(Guid filterId, Exception ex)
        {
            var eventId = 6;

            if (_logger.IsEnabled(LogEventLevel.Error))
                _logger.Error($"{eventId}, ClearResultOutputError {filterId.ToString()}, exception {ex.Message}");
        }

        public void LoadCriteriaTypeOneData(string criteriaEntityField)
        {
            var eventId = 7;

            if (_logger.IsEnabled(LogEventLevel.Information))
                _logger.Information($"{eventId}, LoadCriteriaTypeOneData {criteriaEntityField}");
        }

        public void ComputeClusters(string criteriaEntityField)
        {
            var eventId = 8;

            if (_logger.IsEnabled(LogEventLevel.Information))
                _logger.Information($"{eventId}, ComputeClusters {criteriaEntityField}");
        }

        public void LoadCriteriaTypeOneDataError(string criteriaEntityField, Exception ex)
        {
            var eventId = 9;

            if (_logger.IsEnabled(LogEventLevel.Error))
                _logger.Error($"{eventId}, LoadCriteriaTypeOneDataError {criteriaEntityField}, exception {ex.Message}");
        }

        public void LoadCriteriaTypeSixData(string criteriaEntityField)
        {
            var eventId = 10;

            if (_logger.IsEnabled(LogEventLevel.Information))
                _logger.Information($"{eventId}, LoadCriteriaTypeSixData {criteriaEntityField}");
        }

        public void LoadCriteriaTypeSixDataError(string criteriaEntityField, Guid weightMatrixId, Exception ex)
        {
            var eventId = 11;

            if (_logger.IsEnabled(LogEventLevel.Error))
                _logger.Error($"{eventId}, LoadCriteriaTypeSixDataError {criteriaEntityField}, weightMatrixId {weightMatrixId.ToString()}, exception {ex.Message}");
        }

        public void ListBaseCriteriaError(Exception ex)
        {
            var eventId = 12;

            if (_logger.IsEnabled(LogEventLevel.Error))
                _logger.Error($"{eventId}, ListBaseCriteriaError, exception {ex.Message}");
        }

        public void DeleteCriteria(string argsStr)
        {
            var eventId = 13;

            if (_logger.IsEnabled(LogEventLevel.Information))
                _logger.Information($"{eventId}, DeleteCriteria {argsStr}");
        }

        public void DeleteCriteriaSuccess(string argsStr)
        {
            var eventId = 14;

            if (_logger.IsEnabled(LogEventLevel.Information))
                _logger.Information($"{eventId}, DeleteCriteriaSuccess {argsStr}");
        }

        public void DeleteCriteriaError(string argsStr, Exception ex)
        {
            var eventId = 15;

            if (_logger.IsEnabled(LogEventLevel.Error))
                _logger.Error($"{eventId}, DeleteCriteriaError {argsStr}, exception {ex.Message}");
        }

        public void UpdateCurrentFilterIfDelete(Guid filterId)
        {
            var eventId = 16;

            if (_logger.IsEnabled(LogEventLevel.Information))
                _logger.Information($"{eventId}, UpdateCurrentFilterIfDelete {filterId.ToString()}");
        }

        public void UpdateCurrentFilterIfDeleteSuccess(Guid filterId)
        {
            var eventId = 17;

            if (_logger.IsEnabled(LogEventLevel.Information))
                _logger.Information($"{eventId}, UpdateCurrentFilterIfDeleteSuccess {filterId.ToString()}");
        }

        public void DeleteResultOutput(Guid filterId)
        {
            var eventId = 18;

            if (_logger.IsEnabled(LogEventLevel.Information))
                _logger.Information($"{eventId}, DeleteResultOutput {filterId.ToString()}");
        }

        public void DeleteResultOutputSuccess(Guid filterId)
        {
            var eventId = 19;

            if (_logger.IsEnabled(LogEventLevel.Information))
                _logger.Information($"{eventId}, DeleteResultOutputSuccess {filterId.ToString()}");
        }

        public void DeleteAllCriteria(Guid filterId)
        {
            var eventId = 20;

            if (_logger.IsEnabled(LogEventLevel.Information))
                _logger.Information($"{eventId}, DeleteAllCriteria {filterId.ToString()}");
        }

        public void DeleteAllCriteriaSuccess(Guid filterId)
        {
            var eventId = 21;

            if (_logger.IsEnabled(LogEventLevel.Information))
                _logger.Information($"{eventId}, DeleteAllCriteriaSuccess {filterId.ToString()}");
        }

        public void DeleteFilter(Guid filterId)
        {
            var eventId = 22;

            if (_logger.IsEnabled(LogEventLevel.Information))
                _logger.Information($"{eventId}, DeleteFilter {filterId.ToString()}");
        }

        public void DeleteFilterSuccess(Guid filterId)
        {
            var eventId = 23;

            if (_logger.IsEnabled(LogEventLevel.Information))
                _logger.Information($"{eventId}, DeleteFilterSuccess {filterId.ToString()}");
        }


        public void ReportStatus(int id, string v)
        {
            var eventId = 23;
            if (_logger.IsEnabled(LogEventLevel.Information))
            {
                _logger.Information($"{eventId}, for Process {id}, generated: {v}");
            }
        }
    }
}
